﻿'Nombre:                         AdministracionControl
'Descripcion:                    Control que administra las acciones aplicables a los movimentos
'Dependencias:                 
'Fecha de creación:              20090613
'Autor:                          VMORALES
'Fecha de modifcación:         
'Responsable:                  
'Num. de modifcación:            0

Option Explicit On
Option Strict On

#Region "Imports"

Imports Electrocucaracha.AdminPersonal.DAO
Imports Microsoft.Windows.Controls
Imports System.Collections.Generic
Imports Visifire.Charts
Imports Visifire.Commons
Imports Microsoft.VisualBasic.Constants

#End Region

Namespace Movimiento

    Partial Public Class AdministracionControl

#Region "Constantes"

#End Region

#Region "Miembros"

        Private _movimientos As List(Of Entidades.MovimientoDTO)
        Private _titularesSeleccionados As HashSet(Of Entidades.TitularDTO)
        Private _cuentasSeleccionadas As HashSet(Of Entidades.CuentaDTO)

        'Resumen
        Private total As Decimal = 0
        Private ingresos As Decimal = 0
        Private egresos As Decimal = 0
        Private fechaMinima As Date = Date.Now
        Private fechaMaxima As Date = Date.MinValue
        Private dias As Integer = 0

#End Region

#Region "Propiedades"

        Public ReadOnly Property CuentasSeleccionas() As HashSet(Of Entidades.CuentaDTO)
            Get
                If _cuentasSeleccionadas Is Nothing Then
                    _cuentasSeleccionadas = New HashSet(Of Entidades.CuentaDTO)
                End If

                Return _cuentasSeleccionadas
            End Get
        End Property

        Public ReadOnly Property TitularesSeleccionados() As HashSet(Of Entidades.TitularDTO)
            Get
                If _titularesSeleccionados Is Nothing Then
                    _titularesSeleccionados = New HashSet(Of Entidades.TitularDTO)
                End If

                Return _titularesSeleccionados
            End Get
        End Property

        Public Property Movimientos() As List(Of Entidades.MovimientoDTO)
            Get
                If _movimientos Is Nothing Then
                    _movimientos = New List(Of Entidades.MovimientoDTO)
                End If

                Return _movimientos
            End Get
            Private Set(ByVal value As List(Of Entidades.MovimientoDTO))
                _movimientos = value
            End Set
        End Property

#End Region

#Region "Contructores"

#End Region

#Region "Funciones"

        ''' <summary>
        ''' Funcion utilizada con el proposito de ordenar movimientos a partir de su fecha
        ''' </summary>
        ''' <param name="m">Movimiento a ser comparado</param>
        ''' <param name="m2">Movimiento a ser comparado</param>
        ''' <returns>Numero entero que en caso de ser positivo indica que el primer movimiento tiene precedencia ante el segundo</returns>
        Private Function CompararMovimientosPorFecha(ByVal m As Entidades.MovimientoDTO, ByVal m2 As Entidades.MovimientoDTO) As Integer
            If m Is Nothing Then
                Return If(m2 Is Nothing, 0, -1)
            Else
                If m2 Is Nothing Then
                    Return 1
                Else
                    Return m.Fecha.CompareTo(m2.Fecha)
                End If
            End If
        End Function

        ''' <summary>
        ''' Funcion utilizada con el proposito de ordenar cuentas a partir de su descripcion
        ''' </summary>
        ''' <param name="c">Cuenta a ser comparada</param>
        ''' <param name="c2">Cuenta a ser comparada</param>
        ''' <returns>Numero entero que en caso de ser positivo indica que la primera cuenta tiene precedencia ante la segunda</returns>
        Private Function CompararCuentasPorDescripcion(ByVal c As Entidades.CuentaDTO, ByVal c2 As Entidades.CuentaDTO) As Integer
            If c Is Nothing Then
                Return If(c2 Is Nothing, 0, -1)
            Else
                If c2 Is Nothing Then
                    Return 1
                Else
                    Return c.Descripcion.CompareTo(c2.Descripcion)
                End If
            End If
        End Function

        ''' <summary>
        ''' Funcion que grafica todos los movimientos cargados en el grid
        ''' </summary>
        Private Sub Graficar(ByRef movimientos As IList(Of Entidades.MovimientoDTO))
            Dim grafica As New Chart()
            Dim ds As New DataSeries()
            Dim dpMonto As DataPoint
            Dim total As Decimal = 0

            For Each m As Entidades.MovimientoDTO In movimientos
                total += m.Monto

                dpMonto = New DataPoint()
                dpMonto.AxisXLabel = m.Fecha.ToShortDateString()
                dpMonto.XValue = m.Fecha
                dpMonto.YValue = total
                dpMonto.ToolTipText = String.Format("Cuenta: {0}" + CChar(vbCrLf) _
                                                    + "Descripcion: {1}" + CChar(vbCrLf) _
                                                    + "Fecha: {2}" + CChar(vbCrLf) _
                                                    + "Monto: {3}", m.Cuenta.Descripcion, m.Descripcion, m.Fecha.ToShortDateString(), _
                                                    m.Monto.ToString("$ #,##0.00;($ #,##0.00);"))

                ds.DataPoints.Add(dpMonto)
            Next

            ds.RenderAs = RenderAs.Line

            Me.chrMovimientos.Series.Clear()
            Me.chrMovimientos.Series.Add(ds)
        End Sub

        ''' <summary>
        ''' Funcion que calcula y muestra el total de los movimientos mostrados
        ''' </summary>
        Private Sub CalcularResumen(ByRef movimientos As IList(Of Entidades.MovimientoDTO))
            Dim diferencia As TimeSpan

            For Each m As Entidades.MovimientoDTO In movimientos
                total += m.Monto
                If m.Monto > 0 Then
                    ingresos += m.Monto
                Else
                    egresos += m.Monto
                End If

                If fechaMinima > m.Fecha Then
                    fechaMinima = m.Fecha
                End If

                If fechaMaxima < m.Fecha Then
                    fechaMaxima = m.Fecha
                End If
            Next

            If Not dtDesde.SelectedDate Is Nothing Then
                fechaMinima = dtDesde.SelectedDate.Value
            End If

            If Not dtHasta.SelectedDate Is Nothing Then
                fechaMaxima = dtHasta.SelectedDate.Value
            End If

            diferencia = fechaMaxima.Subtract(fechaMinima)
            dias = diferencia.Days

            Me.lblDias.Content = dias
            If dias > 0 Then
                Me.lblGastoPromedio.Content = (total / dias).ToString("$ #,##0.00;($ #,##0.00);")
            Else
                Me.lblGastoPromedio.Content = "$ 0.00"
            End If

            Me.lblTotal.Content = total.ToString("$ #,##0.00;($ #,##0.00);")
            Me.lblIngresos.Content = ingresos.ToString("$ #,##0.00;($ #,##0.00);")
            Me.lblEgresos.Content = egresos.ToString("$ #,##0.00;($ #,##0.00);")
        End Sub


        ''' <summary>
        ''' Funcion que aplica los filtros selecionados a los movimientos a ser mostrados
        ''' </summary>
        Private Function FiltrarMovimientos() As IList(Of Entidades.MovimientoDTO)
            Dim resultado As IList(Of Entidades.MovimientoDTO) = New List(Of Entidades.MovimientoDTO)(Movimientos)
            Dim iterador As IList(Of Entidades.MovimientoDTO) = New List(Of Entidades.MovimientoDTO)(Movimientos)
            Dim descripcion As String

            'Filtro Desde
            If Not dtDesde.SelectedDate Is Nothing Then
                For Each m As Entidades.MovimientoDTO In iterador
                    If m.Fecha < dtDesde.SelectedDate Then
                        resultado.Remove(m)
                    End If
                Next
            End If

            iterador = New List(Of Entidades.MovimientoDTO)(resultado)

            'Filtro Hasta
            If Not dtHasta.SelectedDate Is Nothing Then
                For Each m As Entidades.MovimientoDTO In iterador
                    If m.Fecha > dtHasta.SelectedDate Then
                        resultado.Remove(m)
                    End If
                Next
            End If

            iterador = New List(Of Entidades.MovimientoDTO)(resultado)

            'Filtro Descripcion
            If Not String.IsNullOrEmpty(txtDescripcion.Text) Then
                descripcion = txtDescripcion.Text.Trim().ToUpper()
                For Each m As Entidades.MovimientoDTO In iterador
                    If Not m.Descripcion.ToUpper().Contains(descripcion) Then
                        resultado.Remove(m)
                    End If
                Next
            End If

            Return resultado
        End Function

        ''' <summary>
        ''' Funcion que carga todas las cuentas relacionadas con el titular seleccionado
        ''' </summary>
        Private Sub CargarCuentas()
            CuentasSeleccionas.Clear()

            Dim cuentas As New List(Of Entidades.CuentaDTO)

            For Each t As Entidades.TitularDTO In TitularesSeleccionados
                For Each c As Entidades.CuentaDTO In Cuenta.Manejador.Dao.Obtener(t)
                    If c.Activo Then
                        cuentas.Add(c)
                    End If
                Next
            Next

            cuentas.Sort(AddressOf CompararCuentasPorDescripcion)

            Me.cmbCuentas.ItemsSource = cuentas
            Me.cmbCuentas.SelectedValuePath = "Id"
        End Sub

        ''' <summary>
        ''' Funcion que carga todos los movimientos relacionados con la cuenta seleccionada
        ''' </summary>
        Private Sub CargarMovimientos()
            Dim movimientosFiltrados As IList(Of Entidades.MovimientoDTO) = FiltrarMovimientos()
            CalcularResumen(movimientosFiltrados)
            Graficar(movimientosFiltrados)

            Me.dgMovimientos.ItemsSource = movimientosFiltrados
        End Sub

        ''' <summary>
        ''' Funcion que obtiene y carga los movimientos de una cuenta en especifica
        ''' </summary>
        ''' <param name="_cuenta">Cuenta a agregar sus movimientos</param>
        Private Sub AgregarMovimientos(ByRef _cuenta As Entidades.CuentaDTO)
            Movimientos.AddRange(Movimiento.Manejador.Dao.Obtener(_cuenta))
            Movimientos.Sort(AddressOf CompararMovimientosPorFecha)

            CargarMovimientos()
        End Sub

        ''' <summary>
        ''' Funcion que obtiene y quita los movimientos de una cuenta en especifica
        ''' </summary>
        ''' <param name="_cuenta">Cuenta a quitar sus movimientos</param>
        Private Sub QuitarMovimientos(ByRef _cuenta As Entidades.CuentaDTO)
            For Each m As Entidades.MovimientoDTO In Movimiento.Manejador.Dao.Obtener(_cuenta)
                If Movimientos.Contains(m) Then
                    Movimientos.Remove(m)
                End If
            Next
            Movimientos.Sort(AddressOf CompararMovimientosPorFecha)

            CargarMovimientos()
        End Sub

        ''' <summary>
        ''' Funcion que carga todos los titulares activos en el combo
        ''' </summary>
        Private Sub CargarTitulares()
            Me.cmbTitulares.ItemsSource = Titular.Manejador.TitularesActivos
            Me.cmbTitulares.SelectedValuePath = "Id"
        End Sub

#End Region

        Private Sub AdministracionControl_Loaded(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Me.Loaded
            CargarTitulares()

            AddHandler Titular.Manejador.TitularesActivosCambiados, AddressOf CargarTitulares
        End Sub

        Private Sub dtDesde_SelectedDateChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles dtDesde.SelectedDateChanged
            CargarMovimientos()
        End Sub

        Private Sub dtHasta_SelectedDateChanged(ByVal sender As System.Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles dtHasta.SelectedDateChanged
            CargarMovimientos()
        End Sub

        Private Sub btnAgregar_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
            Dim w As AdministracionVentana = AdministracionVentana.Instancia
            With w
                .EsEdicion = False
                AddHandler .MovimientoCambiado, AddressOf CargarMovimientos

                .Show()
                .Focus()
            End With
        End Sub

        Private Sub dgMovimientos_SelectionChanged(ByVal sender As Object, ByVal e As System.Windows.Controls.SelectionChangedEventArgs) Handles dgMovimientos.SelectionChanged
            If Not dgMovimientos.SelectedItem Is Nothing Then
                Movimiento.Manejador.Seleccion = DirectCast(Me.dgMovimientos.SelectedItem, Entidades.MovimientoDTO)
                mnuEditar.Visibility = Windows.Visibility.Visible
            Else
                mnuEditar.Visibility = Windows.Visibility.Collapsed
            End If
        End Sub

        Private Sub dgMovimientos_MouseDoubleClick(ByVal sender As System.Object, ByVal e As System.Windows.Input.MouseButtonEventArgs) Handles dgMovimientos.MouseDoubleClick
            Dim w As AdministracionVentana = AdministracionVentana.Instancia
            With w
                .EsEdicion = True
                AddHandler .MovimientoCambiado, AddressOf CargarMovimientos

                .Show()
                .Focus()
            End With
        End Sub

        Private Sub chkCuenta_Checked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
            Dim cuenta As Entidades.CuentaDTO = CType(CType(sender, System.Windows.Controls.CheckBox).DataContext, Entidades.CuentaDTO)
            CuentasSeleccionas.Add(cuenta)
            AgregarMovimientos(cuenta)
        End Sub

        Private Sub chkCuenta_Unchecked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
            Dim cuenta As Entidades.CuentaDTO = CType(CType(sender, System.Windows.Controls.CheckBox).DataContext, Entidades.CuentaDTO)
            CuentasSeleccionas.Remove(cuenta)
            QuitarMovimientos(cuenta)
        End Sub

        Private Sub chkTitular_Checked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
            TitularesSeleccionados.Add(CType(CType(sender, System.Windows.Controls.CheckBox).DataContext, Entidades.TitularDTO))
            CargarCuentas()
        End Sub

        Private Sub chkTitular_Unchecked(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
            TitularesSeleccionados.Remove(CType(CType(sender, System.Windows.Controls.CheckBox).DataContext, Entidades.TitularDTO))
            CargarCuentas()
        End Sub

        Private Sub txtDescripcion_LostFocus(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles txtDescripcion.LostFocus
            CargarMovimientos()
        End Sub

        Private Sub mnuAgregar_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles mnuAgregar.Click
            Dim w As AdministracionVentana = AdministracionVentana.Instancia
            With w
                .EsEdicion = False
                AddHandler .MovimientoCambiado, AddressOf CargarMovimientos

                .Show()
                .Focus()
            End With
        End Sub

        Private Sub mnuEditar_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs) Handles mnuEditar.Click
            Dim w As AdministracionVentana = AdministracionVentana.Instancia
            With w
                .EsEdicion = True
                AddHandler .MovimientoCambiado, AddressOf CargarMovimientos

                .Show()
                .Focus()
            End With
        End Sub
    End Class

End Namespace